#include "avi.h"
#include "mjpeg.h"
#include "videoplayer.h"

#define printf


char* const AVI_VIDS_FLAG_TBL[2] = {"00dc", "01dc"};
char* const AVI_AUDS_FLAG_TBL[2] = {"00wb", "01wb"};

AVISTATUS avi_init(u8 *buf,u16 size)
{
	u16 offset;
	u8 *tbuf;
	AVISTATUS res=AVI_OK;
	AVI_HEADER *aviheader;
	LIST_HEADER *listheader;
	AVIH_HEADER *avihheader;
	STRH_HEADER *strhheader;

	STRF_BMPHEADER *bmpheader;
	STRF_WAVHEADER *wavheader;

	tbuf=buf;
	aviheader=(AVI_HEADER*)buf;
	if(aviheader->RiffID!=AVI_RIFF_ID)return AVI_RIFF_ERR;
	if(aviheader->AviID!=AVI_AVI_ID)return AVI_AVI_ERR;
	buf+=sizeof(AVI_HEADER);
	listheader=(LIST_HEADER*)(buf);
	if(listheader->ListID!=AVI_LIST_ID)return AVI_LIST_ERR;
	if(listheader->ListType!=AVI_HDRL_ID)return AVI_HDRL_ERR;
	buf+=sizeof(LIST_HEADER);
	avihheader=(AVIH_HEADER*)(buf);
	if(avihheader->BlockID!=AVI_AVIH_ID)return AVI_AVIH_ERR;
	g_video_player->avix.SecPerFrame=avihheader->SecPerFrame;
	g_video_player->avix.TotalFrame=avihheader->TotalFrame;
	buf+=avihheader->BlockSize+8;
	listheader=(LIST_HEADER*)(buf);
	if(listheader->ListID!=AVI_LIST_ID)return AVI_LIST_ERR;
	if(listheader->ListType!=AVI_STRL_ID)return AVI_STRL_ERR;
	strhheader=(STRH_HEADER*)(buf+12);
	if(strhheader->BlockID!=AVI_STRH_ID)return AVI_STRH_ERR;
 	if(strhheader->StreamType==AVI_VIDS_STREAM)
	{
		if(strhheader->Handler!=AVI_FORMAT_MJPG)return AVI_FORMAT_ERR;
		g_video_player->avix.VideoFLAG=(u8*)AVI_VIDS_FLAG_TBL[0];
		g_video_player->avix.AudioFLAG=(u8*)AVI_AUDS_FLAG_TBL[1];
		bmpheader=(STRF_BMPHEADER*)(buf+12+strhheader->BlockSize+8);
		if(bmpheader->BlockID!=AVI_STRF_ID)return AVI_STRF_ERR;
		g_video_player->avix.Width=bmpheader->bmiHeader.Width;
		g_video_player->avix.Height=bmpheader->bmiHeader.Height;
		buf+=listheader->BlockSize+8;
		listheader=(LIST_HEADER*)(buf);
		if(listheader->ListID!=AVI_LIST_ID)
		{
			g_video_player->avix.SampleRate=0;
			g_video_player->avix.Channels=0;
			g_video_player->avix.AudioType=0;

		}else
		{
			if(listheader->ListType!=AVI_STRL_ID)return AVI_STRL_ERR;
			strhheader=(STRH_HEADER*)(buf+12);
			if(strhheader->BlockID!=AVI_STRH_ID)return AVI_STRH_ERR;
			if(strhheader->StreamType!=AVI_AUDS_STREAM)return AVI_FORMAT_ERR;
			wavheader=(STRF_WAVHEADER*)(buf+12+strhheader->BlockSize+8);
			if(wavheader->BlockID!=AVI_STRF_ID)return AVI_STRF_ERR;
			g_video_player->avix.SampleRate=wavheader->SampleRate;
			g_video_player->avix.Channels=wavheader->Channels;
			g_video_player->avix.AudioType=wavheader->FormatTag;
		}
	}else if(strhheader->StreamType==AVI_AUDS_STREAM)
	{
		g_video_player->avix.VideoFLAG=(u8*)AVI_VIDS_FLAG_TBL[1];
		g_video_player->avix.AudioFLAG=(u8*)AVI_AUDS_FLAG_TBL[0];
		wavheader=(STRF_WAVHEADER*)(buf+12+strhheader->BlockSize+8);
		if(wavheader->BlockID!=AVI_STRF_ID)return AVI_STRF_ERR;
		g_video_player->avix.SampleRate=wavheader->SampleRate;
		g_video_player->avix.Channels=wavheader->Channels;
		g_video_player->avix.AudioType=wavheader->FormatTag;
		buf+=listheader->BlockSize+8;
		listheader=(LIST_HEADER*)(buf);
		if(listheader->ListID!=AVI_LIST_ID)return AVI_LIST_ERR;
		if(listheader->ListType!=AVI_STRL_ID)return AVI_STRL_ERR;
		strhheader=(STRH_HEADER*)(buf+12);
		if(strhheader->BlockID!=AVI_STRH_ID)return AVI_STRH_ERR;
		if(strhheader->StreamType!=AVI_VIDS_STREAM)return AVI_FORMAT_ERR;
		bmpheader=(STRF_BMPHEADER*)(buf+12+strhheader->BlockSize+8);
		if(bmpheader->BlockID!=AVI_STRF_ID)return AVI_STRF_ERR;
		if(bmpheader->bmiHeader.Compression!=AVI_FORMAT_MJPG)return AVI_FORMAT_ERR;
		g_video_player->avix.Width=bmpheader->bmiHeader.Width;
		g_video_player->avix.Height=bmpheader->bmiHeader.Height;
	}
	offset=avi_srarch_id(tbuf,size, (u8 *)"movi");
	if(offset==0)return AVI_MOVI_ERR;
	if(g_video_player->avix.SampleRate)
	{
		tbuf+=offset;
		offset=avi_srarch_id(tbuf,size,g_video_player->avix.AudioFLAG);
		if(offset==0)return AVI_STREAM_ERR;
		tbuf+=offset+4;
		g_video_player->avix.AudioBufSize=*((u16*)tbuf);
	}
	return res;
}

u16 avi_srarch_id(u8* buf,u16 size,u8 *id)
{
	u16 i;
	size-=4;
	for(i=0;i<size;i++)
	{
	   	if(buf[i]==id[0])
			if(buf[i+1]==id[1])
				if(buf[i+2]==id[2])
					if(buf[i+3]==id[3])return i;
	}
	return 0;
}

AVISTATUS avi_get_streaminfo(u8* buf)
{
	g_video_player->avix.StreamID=MAKE_WORD(buf+2);
	g_video_player->avix.StreamSize=MAKE_DWORD(buf+4);
	if(g_video_player->avix.StreamSize%2)g_video_player->avix.StreamSize++;
	if(g_video_player->avix.StreamID==AVI_VIDS_FLAG||g_video_player->avix.StreamID==AVI_AUDS_FLAG)return AVI_OK;
	if(buf[0]=='i' && buf[1]=='x' && buf[2]=='0' &&buf[3]=='0')return AVI_IX00;
	if(buf[0]==0x69 && buf[1]==0x64 && buf[2]==0x78 &&buf[3]==0x31)return AVI_STREAM_OVER;
	return AVI_STREAM_ERR;
}
